﻿Imports AutoCAD

Public Class CadApplicationServiceImpl
    Implements ICadApplicationService
    Public Shared ZeroPoint As Double() = New Double() {0, 0, 0} '零点
    Public Shared XAxis As Double() = New Double() {1, 0, 0} 'X轴
    Public Shared YAxis As Double() = New Double() {0, 1, 0} 'Y轴
    Public Shared ZAxis As Double() = New Double() {0, 0, 1} 'Z轴

    Public Sub ActivationWCS() Implements ICadApplicationService.ActivationWCS
        Dim this As New CadApplicationServiceImpl
        this.ActivationWCS(this.GetActiveDocument)
        'Throw New NotImplementedException()
    End Sub

    Public Sub ActivationWCS(ByRef doc As AcadDocument) Implements ICadApplicationService.ActivationWCS
        doc.ActiveUCS = WCS(doc)
        'Throw New NotImplementedException()
    End Sub

    Public Shared Function WCS() As AcadUCS
        Dim this As New CadApplicationServiceImpl
        Return this.GetWCS(this.GetActiveDocument)
    End Function

    Public Shared Function WCS(ByRef doc As AcadDocument) As AcadUCS
        Dim this As New CadApplicationServiceImpl
        Return this.GetWCS(doc)
    End Function

    Public Sub BuildLayer(ByRef doc As AcadDocument) Implements ICadApplicationService.BuildLayer
        With doc.Layers
            With .Add("空间")
                .color = AcColor.acYellow
            End With
            With .Add("板件")
                .color = AcColor.acGreen
            End With
            With .Add("加工")
                .color = AcColor.acBlue
            End With
            With .Add("工件")
                .color = AcColor.acCyan
            End With
        End With
    End Sub

    Public Sub BuildLayer() Implements ICadApplicationService.BuildLayer
        Dim doc As AcadDocument = GetActiveDocument()
        BuildLayer(doc)
    End Sub

    Public Sub PurgeAll() Implements ICadApplicationService.PurgeAll
        Dim doc As AcadDocument = GetActiveDocument()
        PurgeAll(doc)
    End Sub

    Public Sub PurgeAll(ByRef doc As AcadDocument) Implements ICadApplicationService.PurgeAll
        doc.PurgeAll()
    End Sub

    Public Function GetApplication() As AcadApplication Implements ICadApplicationService.GetApplication
        Dim app As AcadApplication
        Try
            app = GetObject(, "AutoCAD.Application")
            Return app
        Catch ex As Exception
            MsgBox(ex.Message)
            Return Nothing
        End Try
    End Function





    Public Function GetActiveDocument(ByRef app As AcadApplication) As AcadDocument Implements ICadApplicationService.GetActiveDocument
        Return app.ActiveDocument
    End Function

    Public Function GetActiveDocument() As AcadDocument Implements ICadApplicationService.GetActiveDocument
        Dim app As AcadApplication = GetApplication()
        Return GetActiveDocument(app)
    End Function




    Public Function GetCurrentSelectSet(ByRef doc As AcadDocument) As AcadSelectionSet Implements ICadApplicationService.GetCurrentSelectSet
        Try
            Return doc.PickfirstSelectionSet
        Catch ex As Exception
            MsgBox(ex.Message)
            Return Nothing
        End Try

    End Function

    Public Function GetCurrentSelectSet() As AcadSelectionSet Implements ICadApplicationService.GetCurrentSelectSet
        Dim doc As AcadDocument = GetActiveDocument()
        Return GetCurrentSelectSet(doc)
    End Function

    Public Function Rotate2D(ByRef vector() As Double, angle As Double) As Double() Implements ICadApplicationService.Rotate2D
        Dim p() As Double = vector.Clone
        Dim x As Double = vector(0)
        Dim y As Double = vector(1)

        p(0) = (x * Math.Cos(angle) + y * Math.Sin(angle))
        p(1) = (y * Math.Cos(angle) - x * Math.Sin(angle))
        Return p
    End Function

    ''' <summary>
    ''' 三维旋转点坐标, 该方法已作废, 因为在仅做X轴旋转时会发生错误
    ''' </summary>
    ''' <param name="vector"></param>
    ''' <param name="angle"></param>
    ''' <returns></returns>
    Public Function Rotate3D(ByRef vector() As Double, angle() As Double) As Double() Implements ICadApplicationService.Rotate3D
        Dim p() As Double = vector.Clone()
        Dim x As Double = vector(0)
        Dim y As Double = vector(1)
        Dim z As Double = vector(2)

        'p(0) = x * (Math.Cos(angle(1)) * Math.Cos(angle(2))) + y * (-Math.Cos(angle(0)) * Math.Sin(angle(2)) + Math.Sin(angle(0)) * Math.Sin(angle(1)) * Math.Cos(angle(2))) + z * (Math.Sin(angle(0)) * Math.Sin(angle(2)) + Math.Cos(angle(0)) * Math.Sin(angle(1)) * Math.Cos(angle(2)))
        'p(1) = y * (Math.Cos(angle(1)) * Math.Sin(angle(2))) + y * (Math.Cos(angle(0)) * Math.Cos(angle(2)) + Math.Sin(angle(0)) * Math.Sin(angle(1)) * Math.Sin(angle(2))) + z * (-Math.Sin(angle(0)) * Math.Cos(angle(0)) + Math.Cos(angle(0)) * Math.Sin(angle(1)) * Math.Sin(angle(2)))
        'p(2) = z * (-Math.Sin(angle(1))) + y * (Math.Sin(angle(0)) * Math.Cos(angle(1))) + z * (Math.Cos(angle(0)) * Math.Cos(angle(1)))

        p(0) = x * (Math.Cos(angle(1)) * Math.Cos(angle(2))) + y * (-Math.Cos(angle(0)) * Math.Sin(angle(2)) + Math.Sin(angle(0)) * Math.Sin(angle(1)) * Math.Cos(angle(2))) + z * (Math.Sin(angle(0)) * Math.Sin(angle(2)) + Math.Cos(angle(0)) * Math.Sin(angle(1)) * Math.Cos(angle(2)))
        p(1) = x * (Math.Cos(angle(1)) * Math.Sin(angle(2))) + y * (Math.Cos(angle(0)) * Math.Cos(angle(2)) + Math.Sin(angle(0)) * Math.Sin(angle(1)) * Math.Sin(angle(2))) + z * (-Math.Sin(angle(0)) * Math.Cos(angle(0)) + Math.Cos(angle(0)) * Math.Sin(angle(1)) * Math.Sin(angle(2)))
        p(2) = x * (-Math.Sin(angle(1))) + y * (Math.Sin(angle(0)) * Math.Cos(angle(1))) + z * (Math.Cos(angle(0)) * Math.Cos(angle(1)))

        Return p
    End Function



    Public Function Rotate3D2(ByRef vector() As Double, angle() As Double) As Double() Implements ICadApplicationService.Rotate3D2

        Dim x, y, z As Double
        x = vector(0)
        y = vector(1)
        z = vector(2)

        Dim ax, ay, az As Double
        ax = angle(0)
        ay = angle(1)
        az = angle(2)

        Dim x1, x2, x3 As Double
        Dim y1, y2, y3 As Double
        Dim z1, z2, z3 As Double

        'Z轴旋转
        x1 = x * Math.Cos(az) - y * Math.Sin(az)
        y1 = x * Math.Sin(az) + y * Math.Cos(az)
        z1 = z

        'Y轴旋转
        z2 = z1 * Math.Cos(ay) - x1 * Math.Sin(ay)
        x2 = z1 * Math.Sin(ay) + x1 * Math.Cos(ay)
        y2 = y1

        'X轴旋转
        y3 = y2 * Math.Cos(ax) - z2 * Math.Sin(ax)
        z3 = y2 * Math.Sin(ax) + z2 * Math.Cos(ax)
        x3 = x2

        '返回

        Return New Double() {x3, y3, z3}
    End Function




    Public Function GetEntity() As AcadEntity Implements ICadApplicationService.GetEntity
        Dim doc As AcadDocument = GetActiveDocument()
        Return GetEntity(doc)
    End Function

    Public Function GetEntity(ByRef doc As AcadDocument) As AcadEntity Implements ICadApplicationService.GetEntity
        Dim ent As AcadEntity
        Try
            doc.Utility.GetEntity(ent, Nothing, "拾取图元对象")
            Return ent
        Catch ex As Exception
            MsgBox(ex.Message)
            Return Nothing
        End Try
    End Function

    Public Function GetWCS() As AcadUCS Implements ICadApplicationService.GetWCS
        Dim doc As AcadDocument = GetActiveDocument()
        Return GetWCS(doc)
    End Function

    Public Function GetWCS(ByRef doc As AcadDocument) As AcadUCS Implements ICadApplicationService.GetWCS
        Dim ucs As AcadUCS
        For Each ucs In doc.UserCoordinateSystems
            If ucs.Name = "wcs" Then Return ucs
        Next
        ucs = doc.UserCoordinateSystems.Add(ZeroPoint, XAxis, YAxis, "wcs")
        Return ucs
    End Function

    Public Function RotateEntity(ByRef ent As AcadEntity, ByRef angle() As Double) As AcadEntity Implements ICadApplicationService.RotateEntity
        Dim doc As AcadDocument = ent.Document
        Dim m As Double(,) = GetWCS(doc).GetUCSMatrix
        Dim x() As Double = Rotate3D2(XAxis, angle)
        Dim y() As Double = Rotate3D2(YAxis, angle)
        Dim z() As Double = Rotate3D2(ZAxis, angle)

        m(0, 0) = x(0) : m(0, 1) = y(0) : m(0, 2) = z(0) : m(0, 3) = 0
        m(1, 0) = x(1) : m(1, 1) = y(1) : m(1, 2) = z(1) : m(1, 3) = 0
        m(2, 0) = x(2) : m(2, 1) = y(2) : m(2, 2) = z(2) : m(2, 3) = 0
        m(3, 0) = 0 : m(3, 1) = 0 : m(3, 2) = 0 : m(3, 3) = 1

        ent.TransformBy(m)

        Return ent
    End Function

    Public Function ObjectIdToObject(ByRef objectId As Long) As AcadEntity Implements ICadApplicationService.ObjectIdToObject
        Dim doc As AcadDocument = GetActiveDocument()
        Return ObjectIdToObject(doc, objectId)
    End Function

    Public Function HandleToObject(ByRef handle As String) As AcadEntity Implements ICadApplicationService.HandleToObject
        Dim doc As AcadDocument = GetActiveDocument()
        Return HandleToObject(doc, handle)
    End Function

    Public Function ObjectIdToObject(ByRef doc As AcadDocument, ByRef objectId As Long) As AcadEntity Implements ICadApplicationService.ObjectIdToObject
        Return doc.ObjectIdToObject(objectId)
    End Function

    Public Function HandleToObject(ByRef doc As AcadDocument, ByRef handle As String) As AcadEntity Implements ICadApplicationService.HandleToObject
        Return doc.HandleToObject(handle)
    End Function


End Class
